﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DCT.Service.Restriction.Utility.Log
{
    public abstract class StringLogSkeleton : LogSkeleton
    {
        protected abstract void WriteLine(LogLevel level, string str);

        public override void D(string tag, string msg, Exception exception)
        {
            this.WriteFormatLogString(LogLevel.Debug, tag, msg, exception);
        }

        public override void I(string tag, string msg, Exception exception)
        {
            this.WriteFormatLogString(LogLevel.Info, tag, msg, exception);
        }

        public override void W(string tag, string msg, Exception exception)
        {
            this.WriteFormatLogString(LogLevel.Warning, tag, msg, exception);
        }

        public override void E(string tag, string msg, Exception exception)
        {
            this.WriteFormatLogString(LogLevel.Error, tag, msg, exception);
        }

        public override void F(string tag, string msg, Exception exception)
        {
            this.WriteFormatLogString(LogLevel.Fatal, tag, msg, exception);
        }

        /// <summary>
        /// 格式化日志字符串
        /// </summary>
        /// <param name="level">级别</param>
        /// <param name="tag">标记</param>
        /// <param name="msg">日志信息</param>
        /// <param name="exception">异常</param>
        /// <returns></returns>
        protected virtual string FormatLogString(LogLevel level, string tag, string msg, Exception exception)
        {
            //默认日志格式
            //[时间]$[level]$[日志信息]$[异常信息]
            //异常信息：
            //如果是Debug、Info、Warning，用普通异常信息
            //如果是Error，打印出Stack
            //如果是Fatal，打印异常的所有信息：
            string now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            string levelStr = level.ToString();
            string error = "";
            if (exception != null)
            {
                switch (level)
                {
                    case LogLevel.Debug:
                    case LogLevel.Info:
                    case LogLevel.Warning:
                        {
                            error = LogExtension.FormatException(exception);
                            break;
                        }
                    case LogLevel.Error:
                        {
                            error = LogExtension.FormatExceptionStack(exception);
                            break;
                        }
                    case LogLevel.Fatal:
                        {
                            error = LogExtension.FormatFullException(exception);
                            break;
                        }
                }
            }

            string[] logMessages = null;

            if (string.IsNullOrEmpty(error))
            {
                logMessages = new string[] { now, levelStr, tag, msg };
            }
            else
            {
                logMessages = new string[] { now, levelStr, tag, msg, error };
            }

            return string.Join("$", logMessages);
        }

        public void WriteFormatLogString(LogLevel level, string tag, string msg, Exception exception)
        {
            if (this.EnabledLog(level))
            {
                try
                {
                    this.WriteLine(level, this.FormatLogString(level, tag, msg, exception));
                }
                catch (Exception ex)
                {
                    Console.WriteLine("logerror=>" + LogExtension.FormatFullException(ex));
                }
            }
        }
    }
}
